package top.sxlai.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import top.sxlai.constant.OtherStatus;
import top.sxlai.entity.*;
import top.sxlai.entity.DTO.OpFileDTO;
import top.sxlai.entity.DTO.OpFolderDTO;
import top.sxlai.entity.DTO.ShareDTO;
import top.sxlai.interceptor.LoginInterceptor;
import top.sxlai.mapper.OpSharefileMapper;
import top.sxlai.mapper.OpUserMapper;
import top.sxlai.service.IFileService;
import top.sxlai.service.IFolderService;
import top.sxlai.service.OpSharefileService;
import top.sxlai.util.CurrentSystemTime;
import top.sxlai.util.JwtUtil;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author sxl
 * @since 2024-04-23 16:10:50
 */
@Slf4j
@Service("opSharefileService")
public class OpSharefileServiceImpl extends ServiceImpl<OpSharefileMapper, OpSharefile> implements OpSharefileService {

    @Autowired
    private OpSharefileMapper opSharefileMapper;
    @Autowired
    private OpUserMapper opUserMapper;
    @Autowired
    private IFileService iFileService;
    @Autowired
    private IFolderService iFolderService;

    /**
     * 创建分享
     *
     * @param shareDTO
     * @return
     */
    @Override
    public ResponseEntity<Map<String, String>> createShare(ShareDTO shareDTO) {
        //开始处理
        log.info("开始创建分享,时间:{}", CurrentSystemTime.getTime());
        Map<String, String> response = new HashMap<>();
        //生成8位的uuid
        String shareId = UUID.randomUUID().toString().substring(0, 8);
        //处理有效时间
        int validTime = Integer.parseInt(shareDTO.getValidTime());
        // 获取当前时间戳
        long currentTimeMillis = System.currentTimeMillis();
        // 增加的时间
        long Millis = 24L * 60 * 60 * 1000 * validTime;
        long newMillis = currentTimeMillis + Millis;
        // 创建新的Date对象
        Date tomorrowDate = new Date(newMillis);
        // 格式化日期字符串
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //结束如期
        String endTime = sdf.format(tomorrowDate);
        //开始封装参数
        OpSharefile opSharefile = new OpSharefile();
        opSharefile.setShareid(shareId);
        opSharefile.setSharename(shareDTO.getShareName());
        opSharefile.setHdfspath(shareDTO.getHdfsPath());
        opSharefile.setSharer(shareDTO.getSharer());
        opSharefile.setSharetime(CurrentSystemTime.getTime());
        opSharefile.setEndtime(endTime);
        opSharefile.setFilesize(shareDTO.getFileSize());
        opSharefile.setTimestamp(newMillis);
        opSharefile.setType(shareDTO.getType());
        opSharefile.setCode(shareDTO.getCode());
        opSharefile.setPageview(0);
        opSharefile.setStatus(1);
        int share = opSharefileMapper.createShare(opSharefile);
        if (share != 0) {
            log.info("创建分享成功,时间:{}", CurrentSystemTime.getTime());
            //返回uuid和有效时间
            response.put("shareId", shareId);
            response.put("endTime", endTime);
            response.put("message", OtherStatus.CREATESHARESUCCESS.getMessage());
            return ResponseEntity.ok(response);
        } else {
            log.info("创建分享失败,时间:{}", CurrentSystemTime.getTime());
            response.put("message", OtherStatus.CREATESHAREFAILURE.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }

    @Override
    public ResponseEntity<Map<String, String>> checkShare(String shareId) {
        log.info("开始校验分享链接,时间:{}", CurrentSystemTime.getTime());
        Map<String, String> response = new HashMap<>();
        //每访问一次浏览次数加1
        opSharefileMapper.updatePageView(shareId);
        //查询获取到数据
        OpSharefile opSharefile = opSharefileMapper.checkShare(shareId);
        if (opSharefile != null) {
            //判断是否过期
            long currentTimeMillis = System.currentTimeMillis();
            if (currentTimeMillis > opSharefile.getTimestamp()) {
                log.info("链接过期,时间:{}", CurrentSystemTime.getTime());
                //链接过期，删除链接
                opSharefileMapper.deleteSharing(shareId);
                response.put("message", OtherStatus.SHARELINKEXPIRED.getMessage());
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
            }
            //查询出来分享者的昵称,和头像链接
            OpUser opUser = opUserMapper.getNicknameByUsername(opSharefile.getSharer());
            //返回数据
            response.put("nickName", opUser.getNickname());
            response.put("headImageUrl", opUser.getHeadimageurl());
            response.put("shareName", opSharefile.getSharename());
            response.put("shareTime", opSharefile.getSharetime());
            response.put("endTime", opSharefile.getEndtime());
            response.put("fileSize", String.valueOf(opSharefile.getFilesize()));
            response.put("code", opSharefile.getCode());
            response.put("hdfsPath", opSharefile.getHdfspath());
//            response.put("pageView", String.valueOf(opSharefile.getPageview()));
            log.info("校验分享链接成功,时间:{}", CurrentSystemTime.getTime());
            return ResponseEntity.ok(response);
        }
        response.put("message", OtherStatus.SHARELINKEXPIRED.getMessage());
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
    }
    /**
     * 管理分享
     *
     * @return
     */
    @Override
    public ResponseEntity<List<FileWithFolder>> managementSharing() throws Exception {
        //获取用户id
        log.info("查询分享文件信息,时间:{}", CurrentSystemTime.getTime());
        String userId = JwtUtil.parseJWT(LoginInterceptor.getToken()).getSubject();        //获取用户的账号信息
        OpUser userInfo = opUserMapper.getUserInfo(userId);
        //查询用户分享的文件信息
        List<OpSharefile> isOpShareFilesTime = opSharefileMapper.managementSharing(userInfo.getUsername());
        //先判断是否过期，过期了的进行删除
        for (OpSharefile opShareFile : isOpShareFilesTime) {
            long currentTimeMillis = System.currentTimeMillis();
            if(currentTimeMillis>opShareFile.getTimestamp()){
                //过期了进行删除
                opSharefileMapper.deleteSharing(opShareFile.getShareid());
            }
        }
        //分别查询信息然后封装返回
        List<OpSharefile> opShareFiles = opSharefileMapper.managementSharing(userInfo.getUsername());
        OpFileDTO opFileDTO = new OpFileDTO();
        opFileDTO.setSelectQueryWay("3");//查询类型是3，查询返回全部的文件
        OpFolderDTO opFolderDTO = new OpFolderDTO();
        opFolderDTO.setSelectQueryWay("2");
        //创建返回的对象
        List<FileWithFolder>fileWithFolders = new ArrayList<>();
        //根据分享的类型进行分类
        for (OpSharefile opShareFile : opShareFiles) {

            if ("File".equals(opShareFile.getType())) {
                //封装查询参数
                opFileDTO.setFileFolderPath(opShareFile.getHdfspath());
                //查询文件信息
                ResponseEntity<List<OpFile>> opFiles = iFileService.queryFile(opFileDTO);
                // 获得文件列表
                List<OpFile> fileList = opFiles.getBody();
                assert fileList != null;
                for (OpFile opFile : fileList) {
                    //获取文件的信息
                    FileWithFolder fileData = getFileData(opShareFile, opFile);
                    fileWithFolders.add(fileData);
                }
            } else if ("Folder".equals(opShareFile.getType()))  {
                //封装文件夹查询参数
                opFolderDTO.setHdfsPath(opShareFile.getHdfspath());
                //查询文件夹信息
                ResponseEntity<List<OpFolder>> listResponseEntity = iFolderService.queryFolder(opFolderDTO);
                // 获得文件夹列表
                List<OpFolder> folderList = listResponseEntity.getBody();
                //只保留当前文件夹信息
                List<OpFolder> folders = folderList.stream().filter(opFolder -> opFolder.getHdfsPath().equals(opShareFile.getHdfspath())).collect(Collectors.toList());
                for (OpFolder folder : folders) {
                    FileWithFolder folderData = getFolderData(opShareFile, folder);
                    fileWithFolders.add(folderData);
                }
            }
        }
        return ResponseEntity.ok(fileWithFolders);
    }

    /**
     * 取消分享
     * @param shareDTO
     * @return
     */
    @Override
    public ResponseEntity<Map<String, String>> cancelSharing(ShareDTO shareDTO) {
        log.info("开始取消分享,时间:{}", CurrentSystemTime.getTime());
        Map<String,String> response = new HashMap<>();
        List<String> shareIds = shareDTO.getShareIds();
        for (String shareId : shareIds) {
           opSharefileMapper.deleteSharing(shareId);
        }
        response.put("message",OtherStatus.CANCELSHARESUCCESS.getMessage());
        return ResponseEntity.ok(response);
    }

    private FileWithFolder getFolderData(OpSharefile opShareFile, OpFolder folder) {
        FileWithFolder fileData = new FileWithFolder();
        fileData.setFolderName(folder.getFolderName());
        fileData.setType("Folder");
        fileData.setShareTime(opShareFile.getSharetime());
        fileData.setEndTime(opShareFile.getEndtime());
        fileData.setShareId(opShareFile.getShareid());
        fileData.setShareCode(opShareFile.getCode());
        fileData.setPageValue(opShareFile.getPageview());
        fileData.setStatus(opShareFile.getStatus());
        return fileData;
    }
    private FileWithFolder getFileData(OpSharefile opShareFile, OpFile opFile) {
        FileWithFolder fileData = new FileWithFolder();
        fileData.setFileName(opFile.getFileName());
        fileData.setFileSize(opFile.getFileSize());
        fileData.setType("File");
        fileData.setShareTime(opShareFile.getSharetime());
        fileData.setEndTime(opShareFile.getEndtime());
        fileData.setShareId(opShareFile.getShareid());
        fileData.setShareCode(opShareFile.getCode());
        fileData.setImageUrl(opFile.getImageUrl());
        fileData.setTypeId(opFile.getTypeId());
        fileData.setPageValue(opShareFile.getPageview());
        fileData.setStatus(opShareFile.getStatus());
        return fileData;
    }

}
